#ifndef _SPINLOCK_H_
#define _SPINLOCK_H_

#ifndef LOCK_PREFIX
#define LOCK_PREFIX "LOCK"
#endif

#include <CPU.h>

class Spinlock {
public:
	int TestAndSet() {
		int old;
		asm volatile (LOCK_PREFIX " BTS	$1, %1\n\
				SBBL	%0, %0"
				:"=r" (old)
				:"m" (locked)
				:"memory");
		return old;
	}

	void Lock() {
		while (TestAndSet()) {
			while (locked != 0);
		}
		irqstate = CPU::DisableInt();
	}

	void Unlock() {
		locked = 0;
		if (irqstate)
			CPU::EnableInt();
	}

	inline void Init() {
		locked = 0;
		irqstate = false;
	}

private:
	int locked;
	bool irqstate;
};

#endif
